/*
ID: icerupt1
PROG: cowtour
LANG: C++11
*/

/* solution
 *
 *
*/
#include <fstream>
#include <iostream>
#include <algorithm>
#include <iomanip>

std::ifstream fin {"cowtour.in" };
std::ofstream fout{"cowtour.out"};

struct pos { int x; int y; };

int const maxn = 152;
double dis[maxn][maxn];
double max_dis[maxn];
bool map[maxn][maxn];
pos da[maxn];
int n;

double distance(pos a, pos b)
{
	return std::sqrt((double)(a.x - b.x) * (double)(a.x - b.x)
					+ (double)(a.y - b.y) * (double)(a.y - b.y));
}

int main()
{
	fin >> n;
	for (int i = 0; i < n; i++)
		for (int j = 0; j < n; j++) dis[i][j] = -2;

	for (int i = 0; i < n; i++) fin >> da[i].x >> da[i].y;
	for (int i = 0; i < n; i++)
		for (int j = 0; j < n; j++) {
			char ch; fin >> ch;
			map[i][j] = (ch == '1');
			if (map[i][j]) dis[i][j] = distance(da[i], da[j]);
		}

	for (int k = 0; k < n; k++)
		for (int i = 0; i < n; i++) {
			if (!map[i][k]) continue;
			for (int j = 0; j < n; j++) {
				if (!map[k][j]) continue;
				if (!map[i][j] || dis[i][k] + dis[k][j] < dis[i][j]) {
					dis[i][j] = dis[i][k] + dis[k][j];
					map[i][j] = true;
				}
			}
		}
	for (int i = 0; i < n; i++)
		for (int j = 0; j < n; j++)
			max_dis[i] = std::max(max_dis[i], dis[i][j]);

	double ans = 1<<27;
	for (int i = 0; i < n; i++)
		for (int j = 0; j < n; j++)
			if (!map[i][j] && i != j) {
				if (std::min(ans, distance(da[i], da[j]) + max_dis[i] + max_dis[j])
						!= ans) {
					std::cout << distance(da[i], da[j]) << ' ' << max_dis[i] << ' ' << max_dis[j] << ' ' << ans << '\n';
					std::cout << "distance: " << da[i].x << ' ' << da[i].y << " + "  << da[j].x << ' ' << da[j].y << '\n';
				}
				ans = std::min(ans, distance(da[i], da[j]) + max_dis[i] + max_dis[j]);
			}

	//ans = int(ans * 0e6)*1e-6;
	std::cout << std::setprecision(6) << std::setiosflags(std::ios::fixed) << ans << '\n';
	fout << std::setprecision(6) << std::setiosflags(std::ios::fixed) << ans << '\n';
}
